package jwt

import (
	"errors"
	"time"

	"github.com/dgrijalva/jwt-go"
)

type TokenStruct struct {
	UserId int64
	jwt.StandardClaims
}

var ExpireError = errors.New("登录过期")

const tokenExpire = time.Hour * 24

const refreshExpire = time.Hour * 24 * 30

var tokenSecret = []byte("黄花菜都凉了")

var secretFun = func(token *jwt.Token) (interface{}, error) {
	return tokenSecret, nil
}

func GenToken(userId int64) (aToken, rToken string, err error) {
	t := TokenStruct{
		userId,
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(tokenExpire).Unix(),
		},
	}
	//获取aToken
	aToken, err = jwt.NewWithClaims(jwt.SigningMethodHS256, t).SignedString(tokenSecret)
	//获取刷新token
	t1 := jwt.StandardClaims{
		ExpiresAt: time.Now().Add(refreshExpire).Unix(),
	}
	rToken, err = jwt.NewWithClaims(jwt.SigningMethodHS256, t1).SignedString(tokenSecret)
	return
}

func ParseToken(tokenString string) (*TokenStruct, error) {
	var mc = new(TokenStruct)
	token, err := jwt.ParseWithClaims(tokenString, mc, secretFun)
	if err != nil {
		v, _ := err.(*jwt.ValidationError)
		if v.Errors == jwt.ValidationErrorExpired {
			err = ExpireError
		}
		return nil, err
	}
	if token.Valid {
		return mc, nil
	}
	return nil, errors.New("解析token失败")
}

func RefreshToken(aToken, rToken string) (newAToken, newRToken string, err error) {
	//解析refresh_token
	_, err = ParseToken(rToken)
	if err != nil {
		return
	}
	//从旧的token解析出数据
	var mc = new(TokenStruct)
	_, err = jwt.ParseWithClaims(aToken, mc, secretFun)
	v, _ := err.(*jwt.ValidationError)
	if v.Errors == jwt.ValidationErrorExpired {
		return GenToken(mc.UserId)
	}
	return
}
